package com.example.hzzrpc.config.netty;

import com.example.hzzrpc.config.registrycenter.RpcServerContext;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayDecoder;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import lombok.extern.slf4j.Slf4j;

/**
 * @author ：hzz
 * @description：TODO
 * @date ：2021/5/18 15:22
 */
@Slf4j
public class NettyMainServer extends  BaseChannel  {
    private EventLoopGroup bossGroup;
    private EventLoopGroup workerGroup;
    private ServerBootstrap serverBootstrap;




    public void createNettyServer(RpcServerContext rpcServerContext) throws  Exception{
        initGroup();

        serverBootstrap.option(ChannelOption.SO_KEEPALIVE, keepAlive);
        serverBootstrap.option(ChannelOption.TCP_NODELAY, tcpNoDelay);
        serverBootstrap.option(ChannelOption.SO_BACKLOG, soBacklog);
        serverBootstrap.group(bossGroup, workerGroup);
        serverBootstrap.channel(useEpoll() ? EpollServerSocketChannel.class : NioServerSocketChannel.class);
        serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>(){
            @Override
            protected void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline p = ch.pipeline();
                p.addLast("encoder", new ByteArrayEncoder());
                p.addLast("decoder", new ByteArrayDecoder());
                p.addLast(new NettyServerHandler(rpcServerContext));
               // p.addLast(new ServerIdleStateHandler(0,0,120));
            }
        });
        ChannelFuture future = serverBootstrap.bind(this.getHost(), this.getPort());
        channel = future.channel();
        try {
            future.sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            log.info("Netty服务端监听ip端口:"+this.getHost()+","+this.getPort());
        }
        try {
            future.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
            log.info("关闭netty服务成功");
        }
    }


    private void initGroup() {
        serverBootstrap=new ServerBootstrap();
        if (useEpoll()) {
            bossGroup = new EpollEventLoopGroup(1);
            workerGroup = new EpollEventLoopGroup(10);
        } else {
            bossGroup = new NioEventLoopGroup(1);
            workerGroup = new NioEventLoopGroup(10);
        }

    }


    public boolean useEpoll() {
        String osName = System.getProperty("os.name");
        boolean isLinuxPlatform = osName.toLowerCase().contains("linux");
        return isLinuxPlatform && Epoll.isAvailable();
    }
}
